package com.yvon.maple.cloud.api.base.feign;

import cn.hutool.core.collection.CollUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.yvon.boot.common.result.GlobalException;
import com.yvon.boot.common.result.ResponseData;
import com.yvon.maple.cloud.api.base.dto.FileInfoDTO;
import com.yvon.maple.cloud.api.base.feign.factory.FileFeignFallbackFactory;
import com.yvon.maple.constants.ServiceNameConstant;
import com.yvon.maple.constants.SystemConstant;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;
import java.util.*;

/**
 * @author : Yvon
 * @since : 2021-08-31
 */
@FeignClient(value = ServiceNameConstant.BASE_SERVICE, fallbackFactory = FileFeignFallbackFactory.class)
public interface FileFeignClient {

    String PATH = SystemConstant.Common.FEIGN_INSIDE_URL_PREFIX + "/files";

    /**
     * 通过编号文件信息
     *
     * @param id ID
     * @return {@link ResponseData< FileInfoDTO > }
     * @author : Yvon / 2021-08-31
     */
    @GetMapping(value = PATH + "/id/{id}")
    ResponseData<FileInfoDTO> getById(@PathVariable("id") Long id);

    /**
     * 删除文件
     *
     * @param id ID
     * @return {@link ResponseData<Boolean> }
     * @author : Yvon / 2021-08-31
     */
    @DeleteMapping(PATH + "/id/{id}")
    ResponseData<Boolean> deleteById(@PathVariable("id") Long id);

    /**
     * 批量删除文件
     *
     * @param ids ID集合
     * @return {@link ResponseData<Boolean> }
     * @author : Yvon / 2021-08-31
     */
    @DeleteMapping(PATH)
    ResponseData<Boolean> deleteByIds(@RequestBody List<Long> ids);


    /**
     * 增加保存
     *
     * @param fileIds     文件ID集合
     * @param businessKey 业务关键
     * @return ResponseData<Boolean>
     * @author : Yvon / 2021-10-25
     */
    @PostMapping(PATH + "/incr")
    ResponseData<Boolean> incrSave(@RequestParam(value = "fileIds") @NotNull Set<Long> fileIds, @RequestParam(value = "businessKey") @NotNull String businessKey);


    /**
     * 覆盖保存
     *
     * @param fileIds     文件ID集合
     * @param businessKey 业务关键
     * @return ResponseData<Boolean>
     * @author : Yvon / 2021-10-25
     */
    @PostMapping(PATH + "/cover")
    ResponseData<Boolean> coverSave(@RequestParam(value = "fileIds") Set<Long> fileIds, @RequestParam(value = "businessKey") @NotNull String businessKey);


    /**
     * 临时访问url
     *
     * @param businessKeys 业务键
     * @param hours        小时
     * @return ResponseData<List < String>>
     * @author : Yvon / 2021-10-25
     */
    @GetMapping(PATH + "/key/tempUrl")
    ResponseData<List<String>> getTempUrlByKey(@RequestParam(value = "businessKeys") @NotNull Set<String> businessKeys, @RequestParam(value = "hours", required = false) Integer hours);


    /**
     * 临时访问url
     *
     * @param fileIds 文件ID集合
     * @param hours   小时
     * @return ResponseData<List < String>>
     * @author : Yvon / 2021-10-25
     */
    @GetMapping(PATH + "/id/tempUrl")
    ResponseData<List<String>> tempUrlByFileIds(@RequestParam(value = "fileIds") @NotNull Set<Long> fileIds, @RequestParam(value = "hours", required = false) Integer hours);


    /**
     * 临时访问url
     *
     * @param businessKeys 业务键
     * @param hours        小时
     * @return ResponseData<Map < String, List < String>>>
     * @author : Yvon / 2021-10-25
     */
    @GetMapping(PATH + "/map/tempUrl")
    ResponseData<Map<String, List<String>>> mapTempUrl(@RequestParam(value = "businessKeys") @NotNull Set<String> businessKeys, @RequestParam(value = "hours", required = false) Integer hours);
    /**
     * 文件信息
     *
     * @param businessKeys 业务键
     * @param hours        小时
     * @return ResponseData<List < FileInfoDTO>>
     * @author : Yvon / 2021-10-25
     */
    @GetMapping(PATH + "/info")
    ResponseData<List<FileInfoDTO>> fileInfo(@RequestParam(value = "businessKeys") @NotNull Set<String> businessKeys, @RequestParam(value = "hours", required = false) Integer hours);


    /**
     * 文件信息
     *
     * @param id       ID
     * @param fileKeys 文件的钥匙
     * @return List<FileInfoDTO>
     * @author : Yvon / 2021-10-25
     */
    default List<FileInfoDTO> fileInfo(Long id, Set<String> fileKeys) {
        if (CollUtil.isNotEmpty(fileKeys)) {
            Set<String> businessKeys = new HashSet<>();
            fileKeys.forEach(fileKey -> businessKeys.add(fileKey + id));
            ResponseData<List<FileInfoDTO>> result = fileInfo(businessKeys, null);
            if (ResponseData.isSuccess(result)) {
                return result.getData();
            }else {
                throw new GlobalException(result.getMessage());
            }
        }
        return Lists.newArrayList();
    }

    /**
     * 文件信息
     *
     * @param id      ID
     * @param fileKey 文件的关键
     * @return FileInfoDTO
     * @author : Yvon / 2021-10-25
     */
    default FileInfoDTO fileInfo(Long id, String fileKey) {
        ResponseData<List<FileInfoDTO>> result = fileInfo(Sets.newHashSet(fileKey + id), null);
        if (ResponseData.isSuccess(result)) {
            if (CollUtil.isNotEmpty(result.getData())) {
                return result.getData().get(0);
            }
        }else {
            throw new GlobalException(result.getMessage());
        }
        return null;
    }

    /**
     * 临时访问url
     *
     * @param id      ID
     * @param fileKey 文件的关键
     * @return List<String>
     * @author : Yvon / 2021-10-27
     */
    default List<String> tempUrls(Long id, String fileKey) {
        ResponseData<List<String>> result = getTempUrlByKey(Sets.newHashSet(fileKey + id), null);
        if (ResponseData.isSuccess(result)) {
            return result.getData();
        }else {
            throw new GlobalException(result.getMessage());
        }
    }

    /**
     * 临时访问地址(单个文件，单条业务数据)
     *
     * @param id      ID
     * @param fileKey 文件的关键
     * @return String
     * @author : Yvon / 2021-10-22
     */
    default String tempUrl(Long id, String fileKey) {
        ResponseData<List<String>> result = getTempUrlByKey(Sets.newHashSet(fileKey + id), null);
        if (ResponseData.isSuccess(result)) {
            if (CollUtil.isNotEmpty(result.getData())) {
                return result.getData().get(0);
            }
        }else {
            throw new GlobalException(result.getMessage());
        }
        return null;
    }

    /**
     * 增加保存
     *
     * @param id      ID
     * @param fileKey 文件的关键
     * @param fileId  文件ID
     * @return boolean
     * @author : Yvon / 2021-10-25
     */
    default boolean incrSave(Long id, String fileKey, Long fileId) {
        ResponseData<Boolean> result = incrSave(Sets.newHashSet(fileId), fileKey+id);
        if (ResponseData.isSuccess(result)) {
            return result.getData();
        }else {
            throw new GlobalException(result.getMessage());
        }
    }

    /**
     * 增加保存
     *
     * @param id      ID
     * @param fileKey 文件的关键
     * @param fileIds 文件ID集合
     * @return boolean
     * @author : Yvon / 2021-10-22
     */
    default boolean incrSave(Long id, String fileKey, Set<Long> fileIds) {
        ResponseData<Boolean> result = incrSave(fileIds, fileKey+id);
        if (ResponseData.isSuccess(result)) {
            return result.getData();
        }else {
            throw new GlobalException(result.getMessage());
        }
    }


    /**
     * 覆盖保存
     *
     * @param id      ID
     * @param fileKey 文件的关键
     * @param fileIds 文件ID集合
     * @return boolean
     * @author : Yvon / 2021-10-22
     */
    default boolean coverSave(Long id, String fileKey, Set<Long> fileIds) {
        ResponseData<Boolean> result = coverSave(fileIds, fileKey+id);
        if (ResponseData.isSuccess(result)) {
            return result.getData();
        }else {
            throw new GlobalException(result.getMessage());
        }
    }


    /**
     * 覆盖保存
     *
     * @param id      ID
     * @param fileKey 文件的关键
     * @param fileId  文件ID
     * @return boolean
     * @author : Yvon / 2021-10-25
     */
    default boolean coverSave(Long id, String fileKey, Long fileId) {
        ResponseData<Boolean> result = coverSave(Sets.newHashSet(fileId), fileKey + id);
        if (ResponseData.isSuccess(result)) {
            return result.getData();
        }else {
            throw new GlobalException(result.getMessage());
        }
    }

    /**
     * 批量查询(多条记录, 多个文件)
     *
     * @param businessIds 业务ID集合
     * @param fileKeys    文件的钥匙
     * @return Map<String, String>
     * @author : Yvon / 2021-10-25
     */
    default Map<String, String> tempUrlsMap(Set<Long> businessIds, Set<String> fileKeys) {
        Map<String, String> map = new HashMap<>();
        if (CollUtil.isNotEmpty(businessIds) && CollUtil.isNotEmpty(fileKeys)) {
            Set<String> businessKeys = new HashSet<>();
            businessIds.forEach(businessId -> fileKeys.forEach(fileKey -> businessKeys.add(fileKey + businessId)));
            ResponseData<Map<String, List<String>>> result = mapTempUrl(businessKeys, null);
            if (ResponseData.isSuccess(result)) {
                Map<String, List<String>> data = result.getData();
                if (CollUtil.isNotEmpty(data)) {
                    data.keySet().forEach(key -> {
                        List<String> strings = data.get(key);
                        if (CollUtil.isNotEmpty(strings)) {
                            map.put(key, strings.get(0));
                        }
                    });
                }
            }else {
                throw new GlobalException(result.getMessage());
            }
        }


        return map;
    }


    /**
     * 批量查询(多条记录, 单个文件)
     *
     * @param businessIds 业务ID集合
     * @param fileKey     文件的关键
     * @return Map<String, String>
     * @author : Yvon / 2021-10-25
     */
    default Map<String, String> tempUrlMap(Set<Long> businessIds, String fileKey) {
        Map<String, String> map = new HashMap<>();
        if (CollUtil.isNotEmpty(businessIds) && Objects.nonNull(fileKey)) {
            Set<String> businessKeys = new HashSet<>();
            businessIds.forEach(businessId ->  businessKeys.add(fileKey + businessId));
            ResponseData<Map<String, List<String>>> result = mapTempUrl(businessKeys, null);
            if (ResponseData.isSuccess(result)) {
                Map<String, List<String>> data = result.getData();
                if (CollUtil.isNotEmpty(data)) {
                    data.keySet().forEach(key -> {
                        List<String> strings = data.get(key);
                        if (CollUtil.isNotEmpty(strings)) {
                            map.put(key, strings.get(0));
                        }
                    });
                }
            }else {
                throw new GlobalException(result.getMessage());
            }
        }
        return map;
    }

    /**
     * 批量查询(多条记录, 多个文件)
     *
     * @param businessIds 业务ID集合
     * @param fileKey     文件的关键
     * @return Map<String, List < String>>
     *         map{key: 业务key(businessKey = businessId + fileKey),
     *             value: 业务key对应的文件信息}
     * @author : Yvon / 2021-10-25
     */
    default Map<String, List<String>> tempUrlsMap(Set<Long> businessIds, String fileKey) {
        if (CollUtil.isNotEmpty(businessIds) && Objects.nonNull(fileKey)) {
            Set<String> businessKeys = new HashSet<>();
            businessIds.forEach(businessId -> businessKeys.add(fileKey + businessId));
            ResponseData<Map<String, List<String>>> result = mapTempUrl(businessKeys, null);

            if (ResponseData.isSuccess(result)) {
                return result.getData();
            }else {
                throw new GlobalException(result.getMessage());
            }
        }
        return new HashMap<>();
    }
}
